package com.whitehatsec.sentineldataexchange;

import com.whitehatsec.sentineldataexchange.model.WhiteHatVulnerability;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.SAXException;

/**
 * Repository of WhiteHat Vulnerabilities
 *
 * @author August Detlefsen [augustd@codemagi.com]
 */
public class WhiteHatVulnerabilityLibrary {

	private String whVulnAPI_URL = null;
	private List<WhiteHatVulnerability> vulnerabilities = null;
	private boolean verbose = false;

	public WhiteHatVulnerabilityLibrary(Properties props) {
		this.whVulnAPI_URL = props.getProperty("WHITEHAT_VULN_API_URL");
		this.verbose = props.getProperty("VERBOSE_REPORTING").equalsIgnoreCase("TRUE");
	}

	public WhiteHatVulnerability getVulnerability(int index) {
		return this.vulnerabilities.get(index);
	}

	public List<WhiteHatVulnerability> getVulnerabilities() {
		return vulnerabilities;
	}

	public int getNumberOfVulnerabilities() {
		return this.vulnerabilities.size();
	}

	public void loadVulnerabilities(SentinelLogin login, Integer siteID) {
	    if (siteID == null) {
		String idToLoad = null;
		loadVulnerabilities(login, idToLoad);
	    } else {
		loadVulnerabilities(login, siteID.toString());
	    }
	}
	
	/**
	 * Connect to the WhiteHat Sentinel Vulnerability API
	 * Retrieve the list of vulnerabilities associated with key
	 * Parse the Vuln XML and populate the list of vulnerabilities
	 */
	public void loadVulnerabilities(SentinelLogin login, String siteID) {
		System.out.println("Connecting to the Sentinel Vulnerability API at " + this.whVulnAPI_URL);
		
		String vulnAPIURL = this.whVulnAPI_URL;

		HashMap<String, String> params = new HashMap<String, String>(1);
		params.put("query_status", "open");
		params.put("display_description", "1");
		params.put("display_solution", "1");
		params.put("display_attack_vectors", "1");
		if (siteID != null) {
			params.put("query_site", siteID);
		}

		InputStream vulnsXML = Utils.getUrlAsStream(vulnAPIURL, params, login.getCookies());

		vulnerabilities = parseDocument(vulnsXML);

		if (verbose) {
			System.out.println();
			for (WhiteHatVulnerability vuln : vulnerabilities) {
				System.out.println(vuln.toString());
			}
		}

		System.out.println(this.getNumberOfVulnerabilities() + " vulnerabilities retrieved.");
	}

	/**
	 * Retrieve and Parse WhiteHat Sentinel API XML.
	 */
	public List<WhiteHatVulnerability> parseDocument(InputStream xml) {
		// create a new vulnerability library handler
		WhiteHatVulnerabilityListLoader whVulnListLoader = new WhiteHatVulnerabilityListLoader();

		// create a SAXParser factory
		System.setProperty("javax.xml.parsers.SAXParserFactory", "org.apache.xerces.jaxp.SAXParserFactoryImpl");
		SAXParserFactory spf = SAXParserFactory.newInstance();

		try {
			// create a new instance of parser
			SAXParser sp = spf.newSAXParser();

			// parse the file and register the library handler
			sp.parse(xml, whVulnListLoader);

		} catch (SAXException se) {
			se.printStackTrace(System.err);
		} catch (ParserConfigurationException pce) {
			pce.printStackTrace(System.err);
		} catch (IOException ie) {
			System.err.println("Problem connecting to the WhiteHat Sentinel Vulnerability API");
		} finally {
			Utils.closeStream(xml);
		}

		// return the populated site library
		return whVulnListLoader.getVulnerabilityList();
	}
}
